import React, { memo, useMemo, forwardRef, useState, useImperativeHandle, useEffect } from 'react';
import _ from 'lodash';
import { Table } from 'antd';
import TableColumnWrapper from './tableColumnWrapper';
import { fetchAvailableDictChildList } from '@/services/system/dictionary';
import { formatTree } from '@/utils/utils';
import styles from './tableContent.less';

const defaultColumnWidth = 160; // 累加计算scroll.x值，若列未给定宽度，则取该默认列宽

const TableContent = TableColumnWrapper(
  forwardRef(
    (
      {
        data,
        columns,
        pagination,
        columnComposeParams,
        getColumnSearchProps,
        handleSearch,
        ...restProps
      },
      ref,
    ) => {
      const [columnFilterOpts, setColumnFilterOpts] = useState({});
      const [columnSorterOpts, setColumnSorterOpts] = useState({});
      const [filterDictMappings, setFilterDictMappings] = useState({}); // 字典值集合

      // 列操作以及计算横向滚动的scrollX、异步请求的dictTypes、列筛选的key、列key和dataIndex的对应表dataIndexMapping
      const { tableColumns, dictTypes, columnFilterKey, dataIndexMapping, scrollX } =
        useMemo(() => {
          // console.log('======计算======');
          let tableWidth = 0;
          const dictTypesWithFilter = [];
          const columnFilterKeys = [];
          const dataIndexMappings = {};
          const nextColumns = formatTree(columns, (item) => {
            if (item.children && item.children.length) {
              return { ...item };
            } else {
              const { columnControl, ...columnNode } = item;
              tableWidth += item.width || defaultColumnWidth;
              if (_.isPlainObject(columnControl)) {
                const { typeList, filterOptions, filterDictType } = columnControl;
                if (typeList.length) {
                  if (_.includes(typeList, 'search')) {
                    dataIndexMappings[item.key] = item.dataIndex;
                    _.assign(
                      columnNode,
                      getColumnSearchProps({
                        key: columnNode.key,
                        searchOptions: columnFilterOpts,
                        setSearchOptions: setColumnFilterOpts,
                      }),
                    );
                  } else if (_.includes(typeList, 'transfer') || _.includes(typeList, 'filter')) {
                    let targetFilters = [];
                    targetFilters = _.filter(
                      _.isArray(filterOptions) && !_.isEmpty(filterOptions) ? filterOptions : [],
                      (v) => _.isPlainObject(v),
                    );
                    if (!targetFilters.length) {
                      if (_.isString(filterDictType) && !!filterDictType) {
                        dictTypesWithFilter.push(filterDictType);
                        targetFilters = filterDictMappings[filterDictType] || [];
                      }
                    }
                    const filterTypes = _.filter(
                      _.map(targetFilters, (item) =>
                        _.isString(item) || _.isNumber(item)
                          ? { text: item, value: item }
                          : _.isPlainObject(item)
                          ? item
                          : null,
                      ),
                      (v) => !!v,
                    );
                    _.assign(columnNode, {
                      render: (text, data, index) => {
                        const transText =
                          _.find(filterTypes, ({ value }) => value === text)?.text || text;
                        if (columnNode.customRender) {
                          try {
                            return columnNode.customRender(transText, data, index);
                          } catch (e) {
                            console.log('列自定义渲染异常', e);
                          }
                        }
                        return transText;
                      },
                    });
                    if (_.includes(typeList, 'filter')) {
                      dataIndexMappings[item.key] = item.dataIndex;
                      columnFilterKeys.push(item.key);
                      _.assign(columnNode, {
                        filters: filterTypes,
                        filteredValue: _.isEmpty(columnFilterOpts[columnNode.key])
                          ? null
                          : columnFilterOpts[columnNode.key],
                      });
                    }
                  }
                  if (_.includes(typeList, 'sorter')) {
                    dataIndexMappings[item.key] = item.dataIndex;
                    _.assign(columnNode, {
                      sorter: true,
                      sortOrder: columnSorterOpts[columnNode.dataIndex] || null,
                    });
                  }
                }
              }
              return columnNode;
            }
          });
          return {
            tableColumns: nextColumns,
            scrollX: tableWidth,
            dictTypes: _.uniq(dictTypesWithFilter),
            columnFilterKey: columnFilterKeys,
            dataIndexMapping: dataIndexMappings,
          };
        }, [columns, columnFilterOpts, columnSorterOpts, filterDictMappings]);

      // 方法挂载
      useImperativeHandle(ref, () => ({
        resetTableColumnControl: () => {
          setColumnFilterOpts((prevFilterOpts) => _.mapValues(prevFilterOpts, () => null));
          setColumnSorterOpts({});
        },
      }));

      // 获取字典值列表：{text: string; value: string}[]
      const getDictLabels = async (dictType) => {
        try {
          const res = await fetchAvailableDictChildList({ dictType });
          return _.isArray(res)
            ? _.filter(
                _.map(res, ({ dictValue, dictLabel }) => ({ value: dictValue, text: dictLabel })),
                ({ value }) => _.isString(value) || _.isNumber(value),
              )
            : [];
        } catch (e) {
          return [];
        }
      };
      useEffect(() => {
        if (dictTypes.length) {
          Promise.all(_.map(dictTypes, (str) => getDictLabels(str))).then((result) => {
            setFilterDictMappings(
              _.assign({}, ..._.map(dictTypes, (key, index) => ({ [key]: result[index] }))),
            );
          });
        }
      }, []);

      // 查询
      const handleChange = (pagination, filters, sorter) => {
        const params = [];
        // 更新受控筛选属性
        const nextFilterOpts = _.assign(
          {},
          columnFilterOpts,
          _.pickBy(filters, (v, k) => !v || _.indexOf(columnFilterKey, k) > -1 || _.isString(v)),
        );
        _.forEach(nextFilterOpts, (v, k) => {
          if (!_.isEmpty(v)) {
            if (_.isString(v)) {
              params.push({ column: dataIndexMapping[k], type: 'LIKE', values: v });
            } else if (_.isArray(v)) {
              params.push({ column: dataIndexMapping[k], type: 'IN', values: v.join(',') });
            }
          }
        });
        setColumnFilterOpts(nextFilterOpts);
        // 更新受控排序属性
        const { field, order } = sorter || {};
        if (field && order) {
          params.push({
            column: field,
            type: order === 'ascend' ? 'ORDERBYASC' : 'ORDERBYDESC',
          });
          setColumnSorterOpts({ [field]: order });
        } else {
          setColumnSorterOpts({});
        }

        // 组合分页参数
        const nextParams = _.sortBy(
          _.concat(
            _.filter(
              columnComposeParams,
              ({ column }) => !_.includes(_.values(dataIndexMapping), column),
            ),
            params,
          ),
          'column',
        );
        const searchParams = { params: nextParams };
        if (pagination) {
          _.assign(searchParams, { size: pagination.pageSize, current: pagination.current });
          if (!_.isEqual(columnComposeParams, nextParams)) {
            searchParams.current = 1;
          }
        }
        handleSearch(searchParams);
      };

      return (
        <div className={styles.tableContainer}>
          <Table
            bordered
            columns={tableColumns}
            dataSource={data}
            scroll={{ x: scrollX, y: 496 }}
            onChange={handleChange}
            pagination={
              pagination
                ? _.assign({}, pagination, {
                    small: 'small',
                    simple: false,
                    showQuickJumper: true,
                    showSizeChanger: true,
                    showTotal: (text, range) =>
                      `${range.length ? '第' + range.join('~') + '条 / ' : ''}共${text}条`,
                  })
                : false
            }
            {...restProps}
          />
        </div>
      );
    },
  ),
);

export default memo(
  TableContent,
  (prevProps, nextProps) =>
    prevProps.size === nextProps.size &&
    prevProps.data === nextProps.data &&
    prevProps.columns === nextProps.columns &&
    prevProps.rowSelection === nextProps.rowSelection &&
    prevProps.columnComposeParams === nextProps.columnComposeParams &&
    _.isEqual(prevProps.pagination, nextProps.pagination),
);
